﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Urs.Admin.Models.Settings;
using Urs.Core;
using Urs.Core.Caching;
using Urs.Core.Infrastructure;
using Urs.Data.Domain.Configuration;
using Urs.Data.Domain.Orders;
using Urs.Data.Domain.Payments;
using Urs.Data.Domain.Shipping;
using Urs.Data.Domain.Users;
using Urs.Plugin.Api.Models.Common;
using Plugin.Api.Infrastructure;
using Plugin.Api.Models.Common;
using Plugin.Api.Models.Media;
using Urs.Services;
using Urs.Services.Banners;
using Urs.Services.Directory;
using Urs.Services.Media;
using Urs.Services.Users;
using Urs.Framework.Controllers;

namespace Plugin.Api.Controllers
{
    /// <summary>
    /// 通用接口
    /// </summary>
    [ApiVersion("1.0")]
    [Route("api/v{version:apiVersion}/common")]
    [ApiController]
    public class CommonController : BaseApiController
    {
        private readonly IBannerService _bannerService;
        private readonly IUserService _userService;
        private readonly IAreaService _areaService;
        private readonly ICacheManager _cacheManager;
        private readonly IPictureService _pictureService;
        private readonly OrderSettings _orderSettings;
        private readonly IUrsFileProvider _fileProvider;
        private readonly TemplateSettings _templateSettings;
        private readonly ShoppingCartSettings _shoppingCartSettings;

        /// <summary>
        /// 构造器
        /// </summary>
        public CommonController(IBannerService bannerService,
            IUserService userService,
            IAreaService areaService,
            ICacheManager cacheManager,
            IPictureService pictureService,
            OrderSettings orderSettings,
            IUrsFileProvider fileProvider,
            TemplateSettings templateSettings,
            ShoppingCartSettings shoppingCartSettings)
        {
            this._bannerService = bannerService;
            this._userService = userService;
            this._areaService = areaService;
            this._cacheManager = cacheManager;
            this._pictureService = pictureService;
            this._orderSettings = orderSettings;
            this._fileProvider = fileProvider;
            this._templateSettings = templateSettings;
            this._shoppingCartSettings = shoppingCartSettings;
        }

        #region Util
        [NonAction]
        protected MoPicture PrepareBannerPictureModel(int zoneId, int pictureId, int picsize)
        {
            var pictureModel = new MoPicture()
            {
                BigUrl = _pictureService.GetPictureUrl(pictureId),
                NormalUrl = _pictureService.GetPictureUrl(pictureId, picsize)
            };

            return pictureModel;
        }
        #endregion


        /// <summary>
        /// 获取Banner数据
        /// </summary>
        /// <param name="name">空间名（ZoneName）</param>
        /// <param name="picsize">默认宽50px，根据具体需求传值</param>
        /// <returns></returns>
        [HttpGet("banner")]
        public async Task<ApiResponse<MoBannerZone>> Banner(string name, int picsize = 50)
        {
            var banner = _bannerService.GetByZone(name);

            if (banner == null)
                return ApiResponse<MoBannerZone>.Warn("内容不存在");

            var data = await Task.Run(() =>
              {
                  var model = new MoBannerZone()
                  {
                      ClassName = banner.ClassName,
                      Name = banner.Name,
                      TemplateName = banner.TemplateName,
                      ZoneName = banner.ZoneName
                  };

                  var items = _bannerService.GetItemsById(banner.Id);
                  foreach (var item in items)
                      model.Items.Add(new MoBannerZone.MoBannerItem()
                      {
                          Title = item.Title,
                          SubTitle = item.SubTitle,
                          Url = item.Url,
                          Picture = PrepareBannerPictureModel(banner.Id, item.PictureId, picsize)
                      });
                  return model;
              });

            return ApiResponse<MoBannerZone>.Success(data);
        }
        /// <summary>
        /// 表单信息
        /// </summary>
        /// <param name="name">表单类型</param>
        /// <returns></returns>
        [HttpGet("forminfo")]
        public ApiResponse<MoFormInfo> FormInfo(string name)
        {
            var model = new MoFormInfo();
            return ApiResponse<MoFormInfo>.Success(model);
        }

        /// <summary>
        /// 获取省市区
        /// </summary>
        /// <returns></returns>
        [HttpPost("allprovinces")]
        public async Task<ApiResponse<List<MoProvinces>>> ChinaProvinces()
        {
            var data = await Task.Run(() =>
            {
                var kva = new List<MoProvinces>();
                var provices = _areaService.GetProvinces();
                foreach (var province in provices)
                {
                    var mop = new MoProvinces();
                    mop.ProvinceName = province;
                    var cities = _areaService.GetCities(province);
                    foreach (var city in cities)
                    {
                        var citylist = new MoProvinces.MoCity();
                        citylist.CityName = city;
                        var areas = _areaService.GetAreas(province, city);
                        foreach (var area in areas)
                            citylist.Areas.Add(area);
                        mop.Cities.Add(citylist);
                    }
                    kva.Add(mop);
                }
                return kva;
            });
            return ApiResponse<List<MoProvinces>>.Success(data);
        }
        /// <summary>
        /// 上传图片
        /// </summary>
        /// <param name="upload">图片对接</param>
        /// <returns></returns>
        [ApiAuthorize]
        [ProducesResponseType(typeof(MoBase64), 200)]
        [HttpPost("uploadpicture")]
        public async Task<ApiResponse<MoPictureResponse>> UploadPicture(MoBase64 upload)
        {
            var user = RegisterUser;

            if (string.IsNullOrEmpty(upload.base64Str))
                return ApiResponse<MoPictureResponse>.Warn("base64不能为空");

            try
            {
                var base64Str = upload.base64Str;
                var data = await Task.Run(() =>
                {
                    var mimeType = "image/jpeg";
                    if (base64Str.Contains("base64"))
                    {
                        if (base64Str.Contains("data:image/png;base64,"))
                        {
                            mimeType = "image/png";
                            base64Str = base64Str.Replace("data:image/png;base64,", "");
                        }
                        else if (base64Str.Contains("data:image/jpg;base64,") || base64Str.Contains("data:image/jpeg;base64,"))
                        {
                            mimeType = "image/jpeg";
                            base64Str = base64Str.Replace("data:image/jpeg;base64,", "").Replace("data:image/jpg;base64,", "");
                        }
                        else if (base64Str.Contains("data:image/gif;base64,"))
                        {
                            mimeType = "image/gif";
                            base64Str = base64Str.Replace("data:image/gif;base64,", "");
                        }
                    }
                    byte[] userPictureBinary = Convert.FromBase64String(base64Str);

                    var picture = _pictureService.InsertPicture(userPictureBinary, mimeType, null, true);
                    var model = new MoPictureResponse();
                    model.PictureId = picture.Id;
                    model.BigUrl = _pictureService.GetPictureUrl(picture);
                    model.NormalUrl = _pictureService.GetPictureUrl(picture, upload.pictureSize != 0 ? upload.pictureSize : 100);
                    return model;
                });

                return ApiResponse<MoPictureResponse>.Success(data);
            }
            catch (Exception exc)
            {
                ModelState.AddModelError("", exc.Message);
            }

            return ApiResponse<MoPictureResponse>.Warn(ModelState.FirstMessage());
        }

        /// <summary>
        /// 上传图片 表单提交
        /// </summary>
        /// <param name="Form">Form file文件上传</param>
        /// <returns></returns>
        [ApiAuthorize]
        [HttpPost("picturepost")]
        public async Task<ApiResponse<MoPictureResponse>> PicturePost(IFormCollection form)
        {
            var httpPostedFile = Request.Form.Files.FirstOrDefault();
            if (httpPostedFile == null)
                return ApiResponse<MoPictureResponse>.Warn("无文件上传");

            var pictureSize = 100;
            var fileBinary = GetDownloadBits(httpPostedFile);

            const string qqFileNameParameter = "qqfilename";
            var fileName = httpPostedFile.FileName;
            if (string.IsNullOrEmpty(fileName) && Request.Form.ContainsKey(qqFileNameParameter))
                fileName = Request.Form[qqFileNameParameter].ToString();
            //remove path (passed in IE)
            fileName = _fileProvider.GetFileName(fileName);

            var contentType = httpPostedFile.ContentType;
            pictureSize = ConvertHelper.ToInt32(Request.Form["pictureSize"], pictureSize);

            var fileExtension = _fileProvider.GetFileExtension(fileName);
            if (!string.IsNullOrEmpty(fileExtension))
                fileExtension = fileExtension.ToLowerInvariant();

            //contentType is not always available 
            //that's why we manually update it here
            //http://www.sfsu.edu/training/mimetype.htm
            if (string.IsNullOrEmpty(contentType))
            {
                switch (fileExtension)
                {
                    case ".bmp":
                        contentType = MimeTypes.ImageBmp;
                        break;
                    case ".gif":
                        contentType = MimeTypes.ImageGif;
                        break;
                    case ".jpeg":
                    case ".jpg":
                    case ".jpe":
                    case ".jfif":
                    case ".pjpeg":
                    case ".pjp":
                        contentType = MimeTypes.ImageJpeg;
                        break;
                    case ".png":
                        contentType = MimeTypes.ImagePng;
                        break;
                    case ".tiff":
                    case ".tif":
                        contentType = MimeTypes.ImageTiff;
                        break;
                    default:
                        break;
                }
            }


            var picture = _pictureService.InsertPicture(fileBinary, contentType, null, true);

            var model = new MoPictureResponse();
            model.PictureId = picture.Id;
            model.BigUrl = _pictureService.GetPictureUrl(picture);
            model.NormalUrl = _pictureService.GetPictureUrl(picture, pictureSize);

            return ApiResponse<MoPictureResponse>.Success(model);
        }

        /// <summary>
        /// 获取订单状态信息
        /// </summary>
        /// <returns>键值对</returns>
        [HttpGet("orderstatus")]
        public async Task<ApiResponse<List<KeyValueStrModel>>> GetOrderStatus()
        {
            var data = await Task.Run(() =>
              {
                  return OrderStatus.Pending.ToSelectList(false).Select(l =>
                  {
                      return new KeyValueStrModel()
                      {
                          Key = l.Text,
                          Value = l.Value
                      };
                  }).ToList();
              });

            return ApiResponse<List<KeyValueStrModel>>.Success(data);
        }
        /// <summary>
        /// 获取退款原因
        /// </summary>
        /// <returns>键值对</returns>
        [HttpGet("returnreasons")]
        public async Task<ApiResponse<List<string>>> GetReturnReasons()
        {
            var data = await Task.Run(() =>
            {
                return _orderSettings.AfterSalesReasons;

            });

            return ApiResponse<List<string>>.Success(data);
        }
        /// <summary>
        /// 获取退款操作
        /// </summary>
        /// <returns>键值对</returns>
        [HttpGet("returnactions")]
        public async Task<ApiResponse<List<string>>> GetReturnActions()
        {
            var data = await Task.Run(() =>
            {
                return _orderSettings.AfterSalesActions;
            });

            return ApiResponse<List<string>>.Success(data);
        }
        /// <summary>
        /// 获取用户角色
        /// </summary>
        /// <returns>键值对</returns>
        [HttpGet("userroles")]
        public async Task<ApiResponse<List<MoUserRole>>> GetUserRoles()
        {
            var data = await Task.Run(() =>
            {
                return _userService.GetAllUserRoles()
                .Where(cr => cr.SystemName != SystemRoleNames.Guests)
                .Where(cr => cr.SystemName != SystemRoleNames.Administrators)
                .Select(l =>
                {
                    return new MoUserRole()
                    {
                        Id = l.Id,
                        Name = l.Name,
                        SystemName = l.SystemName
                    };
                }).ToList();
            });

            return ApiResponse<List<MoUserRole>>.Success(data);
        }

        /// <summary>
        /// 获取支付状态信息
        /// </summary>
        /// <returns>键值对</returns>
        [HttpGet("paymentstatus")]
        public async Task<ApiResponse<List<KeyValueStrModel>>> GetPaymentStatus()
        {
            var data = await Task.Run(() =>
              {
                  return PaymentStatus.Pending.ToSelectList(false).Select(l =>
                  {
                      return new KeyValueStrModel()
                      {
                          Key = l.Text,
                          Value = l.Value
                      };
                  }).ToList();
              });

            return ApiResponse<List<KeyValueStrModel>>.Success(data);
        }
        /// <summary>
        /// 获取配送状态信息
        /// </summary>
        /// <returns>键值对</returns>
        [HttpGet("shippingstatus")]
        public async Task<ApiResponse<List<KeyValueStrModel>>> GetShippingStatus()
        {
            var data = await Task.Run(() =>
             {
                 return ShippingStatus.NotYetShipped.ToSelectList(false).Select(l =>
                 {
                     return new KeyValueStrModel()
                     {
                         Key = l.Text,
                         Value = l.Value
                     };
                 }).ToList();
             });

            return ApiResponse<List<KeyValueStrModel>>.Success(data);
        }
        /// <summary>
        /// 添加进购物车的最小商品数量
        /// </summary>
        /// <returns>int</returns>
        [HttpGet("minitemgoodsqty")]
        public ApiResponse<int> MinItemGoodsQuantity()
        {
            var qty = _shoppingCartSettings.MinimunShoppingCartItemGoodsQuantity;

            return ApiResponse<int>.Success(qty);
        }

        public static byte[] GetDownloadBits(IFormFile file)
        {
            using (var fileStream = file.OpenReadStream())
            {
                using (var ms = new MemoryStream())
                {
                    fileStream.CopyTo(ms);
                    var fileBytes = ms.ToArray();
                    return fileBytes;
                }
            }
        }

        /// <summary>
        /// 获取海报模板
        /// </summary>
        [HttpGet("templates")]
        public async Task<ApiResponse<MoTemplateSettings>> GetTemplates()
        {
            var temp = _templateSettings;
            var mo = new MoTemplateSettings()
            {
                Picture1Id = temp.Picture1Id,
                Picture2Id = temp.Picture2Id,
                Picture3Id = temp.Picture3Id,
                Picture1Url = _pictureService.GetPictureUrl(temp.Picture1Id),
                Picture2Url = _pictureService.GetPictureUrl(temp.Picture2Id),
                Picture3Url = _pictureService.GetPictureUrl(temp.Picture3Id),
                AltText1 = temp.AltText1,
                AltText2 = temp.AltText2,
                AltText3 = temp.AltText3,
                Ext1 = temp.Ext1,
                Ext2 = temp.Ext2,
                Ext3 = temp.Ext3,
                SubText1 = temp.SubText1,
                SubText2 = temp.SubText2,
                SubText3 = temp.SubText3,
                Text1 = temp.Text1,
                Text2 = temp.Text2,
                Text3 = temp.Text3,
                Time1 = temp.Time1,
                Time2 = temp.Time2,
                Time3 = temp.Time3,
                Default = temp.Default,
                Enabled = temp.Enabled,
                TianQiId1 = temp.TianQiId1,
                TianQiId2 = temp.TianQiId2,
                TianQiId3 = temp.TianQiId3,
                TianQiId4 = temp.TianQiId4,
                TianQiId5 = temp.TianQiId5,
                TianQiId6 = temp.TianQiId6,
                TianQiId7 = temp.TianQiId7,
                TianQiId1Url = _pictureService.GetPictureUrl(temp.TianQiId1),
                TianQiId2Url = _pictureService.GetPictureUrl(temp.TianQiId2),
                TianQiId3Url = _pictureService.GetPictureUrl(temp.TianQiId3),
                TianQiId4Url = _pictureService.GetPictureUrl(temp.TianQiId4),
                TianQiId5Url = _pictureService.GetPictureUrl(temp.TianQiId5),
                TianQiId6Url = _pictureService.GetPictureUrl(temp.TianQiId6),
                TianQiId7Url = _pictureService.GetPictureUrl(temp.TianQiId7),
            };
            return ApiResponse<MoTemplateSettings>.Success(mo);
        }
    }
}
